package com.irdstudio.efp.nls.service.impl.psd.timedTask;

import com.alibaba.fastjson.JSON;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.basic.framework.core.util.SpringContextUtils;
import com.irdstudio.basic.framework.redis.lock.RedisLock;
import com.irdstudio.basic.sequence.service.DefaultPatternDescriptor;
import com.irdstudio.basic.sequence.service.PatternDescriptor;
import com.irdstudio.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.irdstudio.efp.ctr.service.facade.CtrLoanContService;
import com.irdstudio.efp.ctr.service.vo.CtrLoanContVO;
import com.irdstudio.efp.esb.common.constant.ESBClientConstance;
import com.irdstudio.efp.esb.service.bo.req.psd.PsdSendMsgToTaxReqBean;
import com.irdstudio.efp.esb.service.bo.resp.psd.PsdSendMsgToTaxRespBean;
import com.irdstudio.efp.esb.service.facade.EsbInvokeWrapper;
import com.irdstudio.efp.esb.service.facade.psd.PsdSendMsgToTaxService;
import com.irdstudio.efp.loan.service.facade.AccLoanService;
import com.irdstudio.efp.loan.service.facade.LoanRepayDetailService;
import com.irdstudio.efp.loan.service.vo.AccLoanVO;
import com.irdstudio.efp.loan.service.vo.LoanRepayDetailVO;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import com.irdstudio.efp.nls.service.facade.NlsQueueSoltComnService;
import com.irdstudio.efp.nls.service.facade.PsdSendTaxMessageRecordService;
import com.irdstudio.efp.nls.service.facade.PsdSendTaxRecordService;
import com.irdstudio.efp.nls.service.facade.psd.NlsCreditApprovalInfoService;
import com.irdstudio.efp.nls.service.facade.psd.PreNlsCreditInfoService;
import com.irdstudio.efp.nls.service.facade.psd.SendMsgToTaxService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.NlsApplyInfoVO;
import com.irdstudio.efp.nls.service.vo.PsdSendTaxMessageRecordVO;
import com.irdstudio.efp.nls.service.vo.PsdSendTaxRecordVO;
import com.irdstudio.efp.nls.service.vo.psd.NlsCreditApprovalInfoVO;
import com.irdstudio.efp.nls.service.vo.psd.PreNlsCreditInfoVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.irdstudio.basic.sequence.service.DefaultPatternDescriptor.*;

/**
 * 回写税局处理类
 */
@Service("psdSendMsgToTaxService")
public class SendMsgToTaxServiceImpl implements SendMsgToTaxService {

    private static Logger logger = LoggerFactory.getLogger(SendMsgToTaxServiceImpl.class);

    @Value("${hk.tax.jrcpbh:00000079}")
    private String jrcpbh;

    @Value("${tax.max.hand.num:5}")
    private int maxHandNum;

    @Value("${tax.max.send.day:3}")
    private int maxSendDay;

    @Autowired
    @Qualifier("nlsCreditApprovalInfoService")
    private NlsCreditApprovalInfoService nlsCreditApprovalInfoService;

    @Autowired
    @Qualifier("preNlsCreditInfoService")
    private PreNlsCreditInfoService preNlsCreditInfoService;

    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;

    @Autowired
    @Qualifier("nlsQueueSoltComnService")
    private NlsQueueSoltComnService nlsQueueSoltComnService;

    @Autowired
    @Qualifier("psdWdSendMsgToTaxService")
    private PsdSendMsgToTaxService psdWdSendMsgToTaxService;

    @Autowired
    @Qualifier("ctrLoanContService")
    private CtrLoanContService ctrLoanContService;

    @Autowired
    @Qualifier("accLoanService")
    private AccLoanService accLoanService;

    @Autowired
    private PsdSendTaxRecordService psdSendTaxRecordService;

    @Autowired
    private PsdSendTaxMessageRecordService psdSendTaxMessageRecordService;

    @Autowired
    private NlsApplyInfoService nlsApplyInfoService;

    @Autowired
    private LoanRepayDetailService loanRepayDetailService;

    @Override
    public Boolean sendMsgToTax() {
        try {
            List<NlsCreditApprovalInfoVO> records = nlsCreditApprovalInfoService.getNotSendMsgToTaxRecord();
            if (Objects.nonNull(records) && records.size() > 0) {
                logger.info("普税贷发送税局数据共有" + records.size());
                for (NlsCreditApprovalInfoVO record : records) {
                    if (record.getExcuteTime() < 10) {
                        NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByLmtApplySeq(record.getLmtApplySeq());
                        if (Objects.isNull(nlsCreditInfoVO)) {
                            logger.info("发送信息给税局 授信申请流水号【" + record.getLmtApplySeq() + "】查询不到授信申请信息");
                            continue;
                        }
                        PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
                        preNlsCreditInfoVO.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
                        preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
                        if (Objects.isNull(preNlsCreditInfoVO)) {
                            logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到预授信申请信息");
                            continue;
                        }
                        CtrLoanContVO ctrLoanContVO = new CtrLoanContVO();
                        ctrLoanContVO.setContNo(nlsCreditInfoVO.getLmtApplySeq());
                        ctrLoanContVO = Optional.ofNullable(ctrLoanContService.queryByPk(ctrLoanContVO)).orElseGet(CtrLoanContVO::new);
                        try {
                            double zero = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                            double amount = Optional.ofNullable(nlsCreditInfoVO.getApproveAmt()).orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                            PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
                            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
                            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
                            psdSendMsgToTaxReqBean.setCrFailRsnDesc(record.getRefuseMsg());
                            psdSendMsgToTaxReqBean.setCrtLmt(amount);
                            psdSendMsgToTaxReqBean.setCrIndr("Y".equals(record.getApprResult()) ? "Y" : "N");
                            psdSendMsgToTaxReqBean.setApplySeq(nlsCreditInfoVO.getGlobalSerno());
                            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
                            //不良客户标识
                            psdSendMsgToTaxReqBean.setBadCustIndr(accLoanService.isCusLossCredit(nlsCreditInfoVO.getCusId()) ? "Y" : "N");
                            //贷款余额
                            psdSendMsgToTaxReqBean.setLoanAmt(zero);
                            //贷款金额
                            psdSendMsgToTaxReqBean.setLoanBal(zero);
                            // 还款日期  授信审批日期+12个月
                            try {
                                Instant instant = record.getApproveTime().toInstant();
                                LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
                                String approveDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                                String date = DateUtility.ADD_MONTH(approveDate, Integer.parseInt(Optional.ofNullable(nlsCreditInfoVO.getApplyTerm()).orElse("12").trim())).replace("-", "");
                                // 还款日期
                                psdSendMsgToTaxReqBean.setRpymtDt(date);
                                // 授信到期日
                                psdSendMsgToTaxReqBean.setCrMtrDt(DateUtility.format8To10(date));
                                // 授信开始日
                                psdSendMsgToTaxReqBean.setCrStrtDay(approveDate);

                            } catch (Exception e) {
                                logger.error("发送信息给税局 授信申请流水号【" + record.getLmtApplySeq() + "】还款日期转换失败 " + e.getMessage());
                                continue;
                            }

                            EsbInvokeWrapper esbInvokeWrapper = new EsbInvokeWrapper(psdWdSendMsgToTaxService, psdSendMsgToTaxReqBean, nlsQueueSoltComnService);
                            PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = (PsdSendMsgToTaxRespBean) esbInvokeWrapper.invoke3Threes();
                            logger.info("发送信息给税局 授信申请流水号【" + record.getLmtApplySeq() + "】发送信息税局成功");
                            record.setIsSendToTax("Y");
                            record.setTmstmp(psdSendMsgToTaxRespBean.getTmstmp());
                            record.setTxnSrlNo(psdSendMsgToTaxReqBean.getTxnSrlNo());
                            nlsCreditApprovalInfoService.updateByPrimaryKeySelective(record);
                        } catch (ESBException e) {
                            logger.error("发送信息给税局 授信申请流水号【" + record.getLmtApplySeq() + "】税务局信贷审批结果通知失败 " + e.getMessage());
                            // 记录失败次数 + 1
                            record.setExcuteTime(record.getExcuteTime() + 1);
                            nlsCreditApprovalInfoService.updateByPrimaryKeySelective(record);
                            continue;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            continue;
                        } catch (Exception e) {
                            logger.error("发送信息给税局 授信申请流水号【" + record.getLmtApplySeq() + "】税务局信贷审批结果通知失败" + e.getMessage());
                            continue;
                        }
                    }

                }
            }
        } catch (Exception e) {
            logger.error("税务局信贷审批结果 查询未发送到税局的数据出错" + e.getMessage());
            return false;
        } finally {
            return true;
        }
    }


    // 用作报错回调报错的纳税识别号，如果该纳税识别号发成错误 那么后面的回写会先暂停
    private ArrayList<String> taxNumber = new ArrayList<>();

    @RedisLock(key = "psd_send_tax_taskHandle", expire = 3600)
    @Override
    public Boolean taskHandle() {
        taxNumber.clear();
        //从处理记录表查询需要处理的数据
        PsdSendTaxRecordVO queryParam = new PsdSendTaxRecordVO();
        queryParam.setHandStatus("N");
        queryParam.setHandNum(maxHandNum);
        try {
            List<PsdSendTaxRecordVO> psdSendTaxRecordVOS = psdSendTaxRecordService.queryRecordByStatusAndNum(queryParam);
            if (psdSendTaxRecordVOS.isEmpty()) {
                logger.info("获取到回写税局需要处理的数据为空，本次定时器结束");
                return Boolean.TRUE;
            }
            //轮询处理每一条数据，根据不同数据做不同的操作
            for (PsdSendTaxRecordVO psdSendTaxRecordVO : psdSendTaxRecordVOS) {
                //开始处理
                hand(psdSendTaxRecordVO);
            }
            return Boolean.TRUE;
        } catch (Exception e) {
            logger.info("回写税局发生异常，异常信息为{}", e.getMessage());
        }
        return Boolean.FALSE;
    }

    private void hand(PsdSendTaxRecordVO psdSendTaxRecordVO) {
        //获取处理类型
        String sendType = psdSendTaxRecordVO.getSendType();
        switch (sendType) {
            case "0":
                hand0(psdSendTaxRecordVO);
                break;
            case "1":
                //授信审批
                hand1(psdSendTaxRecordVO);
                break;
            case "2":
                //放款
                hand2(psdSendTaxRecordVO);
                break;
            case "3":
                //主动还款
                hand3(psdSendTaxRecordVO, "02");
                break;
            case "4":
                //提前结清
                hand3(psdSendTaxRecordVO, "03");
                break;
            case "5":
                //批扣还款
                hand5(psdSendTaxRecordVO);
                break;
            case "6":
                //回写还款日期为终止
                hand6(psdSendTaxRecordVO);
                break;
        }
    }

    /**
     * 回写日期为终止
     *
     * @param psdSendTaxRecordVO
     */
    private void hand6(PsdSendTaxRecordVO psdSendTaxRecordVO) {
        boolean updateFlag = true;
        psdSendTaxRecordVO.setHandNum(psdSendTaxRecordVO.getHandNum() + 1);
        NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO = null;
        PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
        PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = new PsdSendMsgToTaxRespBean();
        try {
            NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByLmtApplySeq(psdSendTaxRecordVO.getApplySeq());
            if (Objects.isNull(nlsCreditInfoVO)) {
                logger.info("发送信息给税局 授信申请流水号【" + psdSendTaxRecordVO.getApplySeq() + "】查询不到授信申请信息");
                throw new Exception("查询不到授信申请信息");
            }
            //查询预授信数据
            PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
            preNlsCreditInfoVO.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
            preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
            if (Objects.isNull(preNlsCreditInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到预授信申请信息");
                throw new Exception("查询不到预授信申请信息");
            }
            //判断是否需要暂时拒绝处理
            if (taxNumber.contains(preNlsCreditInfoVO.getTaxIdentificationNumber())) {
                updateFlag = false;
                return;
            }
            psdSendTaxRecordVO.setTaxNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //查询授信审批数据
            nlsCreditApprovalInfoVO = nlsCreditApprovalInfoService.selectByPrimaryKey(psdSendTaxRecordVO.getApplySeq());
            if (Objects.isNull(nlsCreditApprovalInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到授信审批信息");
                throw new Exception("查询不到授信审批信息");
            }
            String[] fstCrdtDt = getFstCrdtDt(nlsCreditInfoVO, preNlsCreditInfoVO);
            //流水号
            psdSendMsgToTaxReqBean.setApplySeq(getSeq(nlsCreditInfoVO.getGlobalSerno()));
            double zero = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double amount = Optional.ofNullable(nlsCreditInfoVO.getApproveAmt()).orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //纳税人识别号
            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //登记序号
            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
            //授信失败原因描述
            psdSendMsgToTaxReqBean.setCrFailRsnDesc(psdSendTaxRecordVO.getApplyMsg());
            //授信额度
            psdSendMsgToTaxReqBean.setCrtLmt(amount);
            //授信标识
            psdSendMsgToTaxReqBean.setCrIndr("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? "Y" : "N");
            //金融产品编号
            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
            //不良客户标识
            psdSendMsgToTaxReqBean.setBadCustIndr(accLoanService.isCusLossCredit(nlsCreditInfoVO.getCusId()) ? "Y" : "N");
            //贷款金额
            psdSendMsgToTaxReqBean.setLoanAmt(new BigDecimal(fstCrdtDt[2]).doubleValue());
            //贷款余额
            psdSendMsgToTaxReqBean.setLoanBal(new BigDecimal(fstCrdtDt[3]).doubleValue());
            // 还款日期  授信审批日期+12个月
            Instant instant = nlsCreditApprovalInfoVO.getApproveTime().toInstant();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            String approveDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            // 还款日期
            psdSendMsgToTaxReqBean.setRpymtDt(psdSendTaxRecordVO.getBizDate());
            // 授信到期日
            psdSendMsgToTaxReqBean.setCrMtrDt(psdSendTaxRecordVO.getBizDate());
            // 授信开始日
            psdSendMsgToTaxReqBean.setCrStrtDay(approveDate);

            //纯粹信用贷款标志Y:是   N：不是
            psdSendMsgToTaxReqBean.setNetCrdtLoanFlg("Y");

            //首次贷款日期 String(8) 格式：YYYY-MM-DD 获取普税贷产品最小期限n'l's
            psdSendMsgToTaxReqBean.setFstCrdtDt(fstCrdtDt[0]);

            //贷款授信期限	String(10)	N
            psdSendMsgToTaxReqBean.setLoanCrTrm("12");

            //累计支用笔数	Double(10,0)	N
            psdSendMsgToTaxReqBean.setAcmlnUseCnt(fstCrdtDt[1]);

            //支用金额	Double(21,2)	N
            psdSendMsgToTaxReqBean.setExpnsUseAmt(new BigDecimal(fstCrdtDt[2]));
            //贷款类型	String(7)	线上：1 或空均可
            psdSendMsgToTaxReqBean.setLoanTp("1");

            psdSendMsgToTaxRespBean = psdWdSendMsgToTaxService.applyPsdSendMsgToTax(psdSendMsgToTaxReqBean);
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, null);
            psdSendTaxRecordVO.setHandStatus("Y");

            logger.info("发送信息给税局 授信申请流水号【" + nlsCreditInfoVO.getLmtApplySeq() + "】发送信息税局成功");
        } catch (Exception e) {
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, e);
            logger.error("发送信息给税局税务局信贷审批结果通知失败" + e.getMessage());
        } finally {
            if (updateFlag) {
                psdSendTaxRecordService.updateByPk(psdSendTaxRecordVO);
            }
        }
    }

    /**
     * 自动还款回调
     *
     * @param psdSendTaxRecordVO
     */
    private void hand5(PsdSendTaxRecordVO psdSendTaxRecordVO) {
        boolean updateFlag = true;
        psdSendTaxRecordVO.setHandNum(psdSendTaxRecordVO.getHandNum() + 1);
        NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO = null;
        PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
        PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = new PsdSendMsgToTaxRespBean();
        try {
            //借据号
            String applySeq = psdSendTaxRecordVO.getApplySeq();
            //查询借据信息
            AccLoanVO billNoParam = new AccLoanVO();
            billNoParam.setBillNo(applySeq);
            AccLoanVO accLoanVO = accLoanService.queryByPk(billNoParam);
            if (Objects.isNull(accLoanVO)) {
                logger.info("主动还款回调查询借据信息");
                throw new Exception("查询不到借据信息，借据号");
            }
            NlsApplyInfoVO pkParam = new NlsApplyInfoVO();
            pkParam.setApplySeq(accLoanVO.getApplySeq());
            NlsApplyInfoVO nlsApplyInfoVO = nlsApplyInfoService.queryByPk(pkParam);
            if (Objects.isNull(nlsApplyInfoVO)) {
                logger.info("支用回调税局，用信申请流水号为：{},获取到的用信申请记录为空", accLoanVO.getApplySeq());
                throw new Exception("查询不到用信申请流水号");
            }
            //授信申请流水号
            String lmtApplySeq = nlsApplyInfoVO.getLmtApplySeq();
            NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByLmtApplySeq(lmtApplySeq);
            if (Objects.isNull(nlsCreditInfoVO)) {
                logger.info("发送信息给税局 授信申请流水号【" + lmtApplySeq + "】查询不到授信申请信息");
                throw new Exception("查询不到授信申请信息");
            }
            //查询预授信数据
            PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
            preNlsCreditInfoVO.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
            preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
            if (Objects.isNull(preNlsCreditInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到预授信申请信息");
                throw new Exception("查询不到预授信申请信息");
            }
            //判断是否需要暂时拒绝处理
            if (taxNumber.contains(preNlsCreditInfoVO.getTaxIdentificationNumber())) {
                updateFlag = false;
                return;
            }
            psdSendTaxRecordVO.setTaxNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //查询授信审批数据
            nlsCreditApprovalInfoVO = nlsCreditApprovalInfoService.selectByPrimaryKey(lmtApplySeq);
            if (Objects.isNull(nlsCreditApprovalInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到授信审批信息");
                throw new Exception("查询不到授信审批信息");
            }
            String[] fstCrdtDt = getFstCrdtDt(nlsCreditInfoVO, preNlsCreditInfoVO);
            //流水号
            psdSendMsgToTaxReqBean.setApplySeq(getSeq(nlsApplyInfoVO.getGlobalSerno()));
            double zero = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double amount = Optional.ofNullable(nlsCreditInfoVO.getApproveAmt()).orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //纳税人识别号
            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //登记序号
            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
            //授信失败原因描述
            //psdSendMsgToTaxReqBean.setCrFailRsnDesc(psdSendTaxRecordVO.getApplyMsg());
            //授信额度
            psdSendMsgToTaxReqBean.setCrtLmt(amount);
            //授信标识
            psdSendMsgToTaxReqBean.setCrIndr("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? "Y" : "N");
            //金融产品编号
            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
            //不良客户标识
            psdSendMsgToTaxReqBean.setBadCustIndr(accLoanService.isCusLossCredit(nlsCreditInfoVO.getCusId()) ? "Y" : "N");
            //贷款金额
            psdSendMsgToTaxReqBean.setLoanAmt(new BigDecimal(fstCrdtDt[2]).doubleValue());
            //贷款余额
            psdSendMsgToTaxReqBean.setLoanBal(new BigDecimal(fstCrdtDt[3]).doubleValue());
            // 还款日期  授信审批日期+12个月
            Instant instant = nlsCreditApprovalInfoVO.getApproveTime().toInstant();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            String approveDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String date = DateUtility.ADD_MONTH(approveDate, Integer.parseInt(Optional.ofNullable(nlsCreditInfoVO.getApplyTerm()).orElse("12").trim())).replace("-", "");
            // 还款日期--
            psdSendMsgToTaxReqBean.setRpymtDt(DateUtility.format10To8(psdSendTaxRecordVO.getBizDate()));
            // 授信到期日
            psdSendMsgToTaxReqBean.setCrMtrDt(DateUtility.format8To10(date));
            // 授信开始日
            psdSendMsgToTaxReqBean.setCrStrtDay(approveDate);

            //纯粹信用贷款标志Y:是   N：不是
            psdSendMsgToTaxReqBean.setNetCrdtLoanFlg("Y");

            //首次贷款日期 String(8) 格式：YYYY-MM-DD 获取普税贷产品最小期限
            psdSendMsgToTaxReqBean.setFstCrdtDt(fstCrdtDt[0]);

            //贷款授信期限	String(10)	N
            psdSendMsgToTaxReqBean.setLoanCrTrm("12");

            //累计支用笔数	Double(10,0)	N
            psdSendMsgToTaxReqBean.setAcmlnUseCnt(fstCrdtDt[1]);

            //支用金额	Double(21,2)	N
            psdSendMsgToTaxReqBean.setExpnsUseAmt(new BigDecimal(fstCrdtDt[2]));
            //贷款类型	String(7)	线上：1 或空均可
            psdSendMsgToTaxReqBean.setLoanTp("1");

            psdSendMsgToTaxRespBean = psdWdSendMsgToTaxService.applyPsdSendMsgToTax(psdSendMsgToTaxReqBean);
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, null);
            psdSendTaxRecordVO.setHandStatus("Y");

            logger.info("发送信息给税局 借据号【" + nlsCreditInfoVO.getLmtApplySeq() + "】发送信息税局成功");
        } catch (Exception e) {
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, e);
            logger.error("发送信息给税务局信贷审批结果通知失败" + e.getMessage());
        } finally {
            if (updateFlag) {
                psdSendTaxRecordService.updateByPk(psdSendTaxRecordVO);
            }
        }
    }

    /**
     * 还款回调
     *
     * @param psdSendTaxRecordVO
     * @param setlType           还款类型 02提前部分还款 03提前结清
     */
    private void hand3(PsdSendTaxRecordVO psdSendTaxRecordVO, String setlType) {
        boolean updateFlag = true;
        psdSendTaxRecordVO.setHandNum(psdSendTaxRecordVO.getHandNum() + 1);
        NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO = null;
        PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
        PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = new PsdSendMsgToTaxRespBean();
        try {
            //还款申请流水号
            String applySeq = psdSendTaxRecordVO.getApplySeq();
            //查询还款记录
            List<LoanRepayDetailVO> loanRepayDetailVOS = loanRepayDetailService.queryBySetlSeq(applySeq);
            if (loanRepayDetailVOS.isEmpty()) {
                logger.info("主动还款回调查询不到还款流水记录");
                throw new Exception("查询不到还款流水记录");
            }
            //查询借据信息
            AccLoanVO billNoParam = new AccLoanVO();
            billNoParam.setBillNo(loanRepayDetailVOS.get(0).getLoanNo());
            AccLoanVO accLoanVO = accLoanService.queryByPk(billNoParam);
            if (Objects.isNull(accLoanVO)) {
                logger.info("主动还款回调查询借据信息");
                throw new Exception("查询不到借据信息，借据号");
            }
            NlsApplyInfoVO pkParam = new NlsApplyInfoVO();
            pkParam.setApplySeq(accLoanVO.getApplySeq());
            NlsApplyInfoVO nlsApplyInfoVO = nlsApplyInfoService.queryByPk(pkParam);
            if (Objects.isNull(nlsApplyInfoVO)) {
                logger.info("支用回调税局，用信申请流水号为：{},获取到的用信申请记录为空", accLoanVO.getApplySeq());
                throw new Exception("查询不到用信申请流水号");
            }
            //授信申请流水号
            String lmtApplySeq = nlsApplyInfoVO.getLmtApplySeq();
            NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByLmtApplySeq(lmtApplySeq);
            if (Objects.isNull(nlsCreditInfoVO)) {
                logger.info("发送信息给税局 授信申请流水号【" + lmtApplySeq + "】查询不到授信申请信息");
                throw new Exception("查询不到授信申请信息");
            }
            //查询预授信数据
            PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
            preNlsCreditInfoVO.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
            preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
            if (Objects.isNull(preNlsCreditInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到预授信申请信息");
                throw new Exception("查询不到预授信申请信息");
            }
            //判断是否需要暂时拒绝处理
            if (taxNumber.contains(preNlsCreditInfoVO.getTaxIdentificationNumber())) {
                updateFlag = false;
                return;
            }
            psdSendTaxRecordVO.setTaxNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //查询授信审批数据
            nlsCreditApprovalInfoVO = nlsCreditApprovalInfoService.selectByPrimaryKey(lmtApplySeq);
            if (Objects.isNull(nlsCreditApprovalInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到授信审批信息");
                throw new Exception("查询不到授信审批信息");
            }
            String[] fstCrdtDt = getFstCrdtDt(nlsCreditInfoVO, preNlsCreditInfoVO);
            //流水号
            psdSendMsgToTaxReqBean.setApplySeq(getSeq(loanRepayDetailVOS.get(0).getGlobalSerno()));
            double zero = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double amount = Optional.ofNullable(nlsCreditInfoVO.getApproveAmt()).orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //纳税人识别号
            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //登记序号
            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
            //授信失败原因描述
            //psdSendMsgToTaxReqBean.setCrFailRsnDesc(psdSendTaxRecordVO.getApplyMsg());
            //授信额度
            psdSendMsgToTaxReqBean.setCrtLmt(amount);
            //授信标识
            psdSendMsgToTaxReqBean.setCrIndr("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? "Y" : "N");
            //金融产品编号
            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
            //不良客户标识
            psdSendMsgToTaxReqBean.setBadCustIndr(accLoanService.isCusLossCredit(nlsCreditInfoVO.getCusId()) ? "Y" : "N");
            //贷款金额
            psdSendMsgToTaxReqBean.setLoanAmt(new BigDecimal(fstCrdtDt[2]).doubleValue());
            //贷款余额
            psdSendMsgToTaxReqBean.setLoanBal(new BigDecimal(fstCrdtDt[3]).doubleValue());
            // 还款日期  授信审批日期+12个月
            Instant instant = nlsCreditApprovalInfoVO.getApproveTime().toInstant();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            String approveDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String date = DateUtility.ADD_MONTH(approveDate, Integer.parseInt(Optional.ofNullable(nlsCreditInfoVO.getApplyTerm()).orElse("12").trim())).replace("-", "");
            // 还款日期--
            if (setlType.equals("03")) {
                psdSendMsgToTaxReqBean.setRpymtDt(date);
            } else {
                psdSendMsgToTaxReqBean.setRpymtDt(DateUtility.format10To8(loanRepayDetailVOS.get(0).getSetlValDt()));
            }
            // 授信到期日
            psdSendMsgToTaxReqBean.setCrMtrDt(DateUtility.format8To10(date));
            // 授信开始日
            psdSendMsgToTaxReqBean.setCrStrtDay(approveDate);

            //纯粹信用贷款标志Y:是   N：不是
            psdSendMsgToTaxReqBean.setNetCrdtLoanFlg("Y");

            //首次贷款日期 String(8) 格式：YYYY-MM-DD 获取普税贷产品最小期限
            psdSendMsgToTaxReqBean.setFstCrdtDt(fstCrdtDt[0]);

            //贷款授信期限	String(10)	N
            psdSendMsgToTaxReqBean.setLoanCrTrm("12");

            //累计支用笔数	Double(10,0)	N
            psdSendMsgToTaxReqBean.setAcmlnUseCnt(fstCrdtDt[1]);

            //支用金额	Double(21,2)	N
            psdSendMsgToTaxReqBean.setExpnsUseAmt(new BigDecimal(fstCrdtDt[2]));
            //贷款类型	String(7)	线上：1 或空均可
            psdSendMsgToTaxReqBean.setLoanTp("1");

            psdSendMsgToTaxRespBean = psdWdSendMsgToTaxService.applyPsdSendMsgToTax(psdSendMsgToTaxReqBean);
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, null);
            psdSendTaxRecordVO.setHandStatus("Y");

            logger.info("发送信息给税局 授信申请流水号【" + nlsCreditInfoVO.getLmtApplySeq() + "】发送信息税局成功");
        } catch (Exception e) {
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, e);
            logger.error("发送信息给税务局信贷审批结果通知失败" + e.getMessage());
        } finally {
            if (updateFlag) {
                psdSendTaxRecordService.updateByPk(psdSendTaxRecordVO);
            }
        }
    }

    /**
     * 支用回调
     *
     * @param psdSendTaxRecordVO
     */
    private void hand2(PsdSendTaxRecordVO psdSendTaxRecordVO) {
        boolean updateFlag = true;
        psdSendTaxRecordVO.setHandNum(psdSendTaxRecordVO.getHandNum() + 1);
        NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO = null;
        PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
        PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = new PsdSendMsgToTaxRespBean();
        try {
            //用信申请流水号
            String applySeq = psdSendTaxRecordVO.getApplySeq();
            NlsApplyInfoVO pkParam = new NlsApplyInfoVO();
            pkParam.setApplySeq(applySeq);
            NlsApplyInfoVO nlsApplyInfoVO = nlsApplyInfoService.queryByPk(pkParam);
            if (Objects.isNull(nlsApplyInfoVO)) {
                logger.info("支用回调税局，用信申请流水号为：{},获取到的用信申请记录为空", applySeq);
                throw new Exception("查询不到用信申请流水号");
            }
            //授信申请流水号
            String lmtApplySeq = nlsApplyInfoVO.getLmtApplySeq();
            NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByLmtApplySeq(lmtApplySeq);
            if (Objects.isNull(nlsCreditInfoVO)) {
                logger.info("发送信息给税局 授信申请流水号【" + lmtApplySeq + "】查询不到授信申请信息");
                throw new Exception("查询不到授信申请信息");
            }
            //查询预授信数据
            PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
            preNlsCreditInfoVO.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
            preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
            if (Objects.isNull(preNlsCreditInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到预授信申请信息");
                throw new Exception("查询不到预授信申请信息");
            }
            //判断是否需要暂时拒绝处理
            if (taxNumber.contains(preNlsCreditInfoVO.getTaxIdentificationNumber())) {
                updateFlag = false;
                return;
            }
            psdSendTaxRecordVO.setTaxNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //查询授信审批数据
            nlsCreditApprovalInfoVO = nlsCreditApprovalInfoService.selectByPrimaryKey(lmtApplySeq);
            if (Objects.isNull(nlsCreditApprovalInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到授信审批信息");
                throw new Exception("查询不到授信审批信息");
            }
            String[] fstCrdtDt = getFstCrdtDt(nlsCreditInfoVO, preNlsCreditInfoVO);
            //流水号
            psdSendMsgToTaxReqBean.setApplySeq(getSeq(nlsApplyInfoVO.getGlobalSerno()));
            double zero = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double amount = Optional.ofNullable(nlsCreditInfoVO.getApproveAmt()).orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //纳税人识别号
            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //登记序号
            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
            //授信失败原因描述
            //psdSendMsgToTaxReqBean.setCrFailRsnDesc(psdSendTaxRecordVO.getApplyMsg());
            //授信额度
            psdSendMsgToTaxReqBean.setCrtLmt(amount);
            //授信标识
            psdSendMsgToTaxReqBean.setCrIndr("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? "Y" : "N");
            //金融产品编号
            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
            //不良客户标识
            psdSendMsgToTaxReqBean.setBadCustIndr(accLoanService.isCusLossCredit(nlsCreditInfoVO.getCusId()) ? "Y" : "N");
            //贷款金额
            psdSendMsgToTaxReqBean.setLoanAmt(new BigDecimal(fstCrdtDt[2]).doubleValue());
            //贷款余额
            psdSendMsgToTaxReqBean.setLoanBal(new BigDecimal(fstCrdtDt[3]).doubleValue());
            // 还款日期  授信审批日期+12个月
            Instant instant = nlsCreditApprovalInfoVO.getApproveTime().toInstant();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            String approveDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String date = DateUtility.ADD_MONTH(approveDate, Integer.parseInt(Optional.ofNullable(nlsCreditInfoVO.getApplyTerm()).orElse("12").trim())).replace("-", "");
            // 还款日期
            psdSendMsgToTaxReqBean.setRpymtDt(date);
            // 授信到期日
            psdSendMsgToTaxReqBean.setCrMtrDt(DateUtility.format8To10(date));
            // 授信开始日
            psdSendMsgToTaxReqBean.setCrStrtDay(approveDate);

            //纯粹信用贷款标志Y:是   N：不是
            psdSendMsgToTaxReqBean.setNetCrdtLoanFlg("Y");

            //首次贷款日期 String(8) 格式：YYYY-MM-DD 获取普税贷产品最小期限n'l's
            psdSendMsgToTaxReqBean.setFstCrdtDt(fstCrdtDt[0]);

            //贷款授信期限	String(10)	N
            psdSendMsgToTaxReqBean.setLoanCrTrm("12");

            //累计支用笔数	Double(10,0)	N
            psdSendMsgToTaxReqBean.setAcmlnUseCnt(fstCrdtDt[1]);

            //支用金额	Double(21,2)	N
            psdSendMsgToTaxReqBean.setExpnsUseAmt(new BigDecimal(fstCrdtDt[2]));
            //贷款类型	String(7)	线上：1 或空均可
            psdSendMsgToTaxReqBean.setLoanTp("1");

            psdSendMsgToTaxRespBean = psdWdSendMsgToTaxService.applyPsdSendMsgToTax(psdSendMsgToTaxReqBean);
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, null);
            psdSendTaxRecordVO.setHandStatus("Y");

            logger.info("发送信息给税局 授信申请流水号【" + nlsCreditInfoVO.getLmtApplySeq() + "】发送信息税局成功");
        } catch (Exception e) {
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, e);
            logger.error("发送信息给税局税务局信贷审批结果通知失败" + e.getMessage());
        } finally {
            if (updateFlag) {
                psdSendTaxRecordService.updateByPk(psdSendTaxRecordVO);
            }
        }
    }

    /**
     * 授信审批回调
     *
     * @param psdSendTaxRecordVO
     */
    private void hand1(PsdSendTaxRecordVO psdSendTaxRecordVO) {
        boolean updateFlag = true;
        psdSendTaxRecordVO.setHandNum(psdSendTaxRecordVO.getHandNum() + 1);
        NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO = null;
        PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
        PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = new PsdSendMsgToTaxRespBean();
        try {
            NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByLmtApplySeq(psdSendTaxRecordVO.getApplySeq());
            if (Objects.isNull(nlsCreditInfoVO)) {
                logger.info("发送信息给税局 授信申请流水号【" + psdSendTaxRecordVO.getApplySeq() + "】查询不到授信申请信息");
                throw new Exception("查询不到授信申请信息");
            }
            //查询预授信数据
            PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
            preNlsCreditInfoVO.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
            preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
            if (Objects.isNull(preNlsCreditInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到预授信申请信息");
                throw new Exception("查询不到预授信申请信息");
            }
            //判断是否需要暂时拒绝处理
            if (taxNumber.contains(preNlsCreditInfoVO.getTaxIdentificationNumber())) {
                updateFlag = false;
                return;
            }
            psdSendTaxRecordVO.setTaxNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //查询授信审批数据
            nlsCreditApprovalInfoVO = nlsCreditApprovalInfoService.selectByPrimaryKey(psdSendTaxRecordVO.getApplySeq());
            if (Objects.isNull(nlsCreditApprovalInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + nlsCreditInfoVO.getPreLmtApplySeq() + "】查询不到授信审批信息");
                throw new Exception("查询不到授信审批信息");
            }
            String[] fstCrdtDt = getFstCrdtDt(nlsCreditInfoVO, preNlsCreditInfoVO);
            //流水号
            psdSendMsgToTaxReqBean.setApplySeq(getSeq(nlsCreditInfoVO.getGlobalSerno()));
            double zero = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double amount = Optional.ofNullable(nlsCreditInfoVO.getApproveAmt()).orElse(BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //纳税人识别号
            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //登记序号
            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
            //授信失败原因描述
            psdSendMsgToTaxReqBean.setCrFailRsnDesc(psdSendTaxRecordVO.getApplyMsg());
            //授信额度
            psdSendMsgToTaxReqBean.setCrtLmt("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? amount : 0.00);
            //授信标识
            psdSendMsgToTaxReqBean.setCrIndr("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? "Y" : "N");
            //金融产品编号
            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
            //不良客户标识
            psdSendMsgToTaxReqBean.setBadCustIndr(accLoanService.isCusLossCredit(nlsCreditInfoVO.getCusId()) ? "Y" : "N");
            //贷款金额
            psdSendMsgToTaxReqBean.setLoanAmt("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? new BigDecimal(fstCrdtDt[2]).doubleValue() : zero);
            //贷款余额
            psdSendMsgToTaxReqBean.setLoanBal("Y".equals(psdSendTaxRecordVO.getApplyStatus()) ? new BigDecimal(fstCrdtDt[3]).doubleValue() : zero);
            // 还款日期  授信审批日期+12个月
            Instant instant = nlsCreditApprovalInfoVO.getApproveTime().toInstant();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            String approveDate = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String date = DateUtility.ADD_MONTH(approveDate, Integer.parseInt(Optional.ofNullable(nlsCreditInfoVO.getApplyTerm()).orElse("12").trim())).replace("-", "");
            // 还款日期
            psdSendMsgToTaxReqBean.setRpymtDt(date);
            // 授信到期日
            psdSendMsgToTaxReqBean.setCrMtrDt(DateUtility.format8To10(date));
            // 授信开始日
            psdSendMsgToTaxReqBean.setCrStrtDay(approveDate);

            //纯粹信用贷款标志Y:是   N：不是
            psdSendMsgToTaxReqBean.setNetCrdtLoanFlg("Y");

            //首次贷款日期 String(8) 格式：YYYY-MM-DD 获取普税贷产品最小期限n'l's
            psdSendMsgToTaxReqBean.setFstCrdtDt(fstCrdtDt[0]);

            //贷款授信期限	String(10)	N
            psdSendMsgToTaxReqBean.setLoanCrTrm("12");

            //累计支用笔数	Double(10,0)	N
            psdSendMsgToTaxReqBean.setAcmlnUseCnt(fstCrdtDt[1]);

            //支用金额	Double(21,2)	N
            psdSendMsgToTaxReqBean.setExpnsUseAmt(new BigDecimal(fstCrdtDt[2]));
            //贷款类型	String(7)	线上：1 或空均可
            psdSendMsgToTaxReqBean.setLoanTp("1");

            psdSendMsgToTaxRespBean = psdWdSendMsgToTaxService.applyPsdSendMsgToTax(psdSendMsgToTaxReqBean);
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, null);
            psdSendTaxRecordVO.setHandStatus("Y");

            logger.info("发送信息给税局 授信申请流水号【" + nlsCreditInfoVO.getLmtApplySeq() + "】发送信息税局成功");
        } catch (Exception e) {
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, e);
            logger.error("发送信息给税局税务局信贷审批结果通知失败" + e.getMessage());
        } finally {
            if (updateFlag) {
                psdSendTaxRecordService.updateByPk(psdSendTaxRecordVO);
            }
        }
    }

    /**
     * -- 查询出已经审批了的预授信数据 判断有哪些数据没有授信回写
     * #1、预授信申请日期距离当前已经超过三天
     * #2、预授信没有授信申请记录
     * #3、预授信有授信申请记录，但是没有授信回写记录
     *
     * @param psdSendTaxRecordVO
     */
    private void hand0(PsdSendTaxRecordVO psdSendTaxRecordVO) {
        boolean updateFlag = false;
        psdSendTaxRecordVO.setHandNum(psdSendTaxRecordVO.getHandNum() + 1);
        PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean = new PsdSendMsgToTaxReqBean();
        PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean = new PsdSendMsgToTaxRespBean();
        try {
            //查询预授信数据
            PreNlsCreditInfoVO preNlsCreditInfoVO = new PreNlsCreditInfoVO();
            preNlsCreditInfoVO.setApplySeq(psdSendTaxRecordVO.getApplySeq());
            preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(preNlsCreditInfoVO);
            if (Objects.isNull(preNlsCreditInfoVO)) {
                logger.info("发送信息给税局 预授信授信申请流水号【" + psdSendTaxRecordVO.getApplySeq() + "】查询不到预授信申请信息");
                throw new Exception("查询不到预授信申请信息");
            }

            Date createTime = psdSendTaxRecordVO.getCreateTime();
            //判断是否已经超过三天
            LocalDateTime localDateTime = LocalDateTime.ofInstant(createTime.toInstant(), ZoneId.systemDefault());
            LocalDate localDate = localDateTime.toLocalDate();
            LocalDate localDate1 = localDate.plusDays(maxSendDay);
            LocalDate now = LocalDate.now();
            if (now.isBefore(localDate1)) {
                logger.info("时间没到t+7，暂不处理该回写，回写记录流水号：{}", psdSendTaxRecordVO.getApplyMsg());
                return;
            }
            //根据纳税识别号判断时间内是否有授信回写记录 如果存在则不处理回写，如果不存在 则回写失败
            List<PsdSendTaxRecordVO> psdSendTaxRecordVOS = psdSendTaxRecordService.queryRecordByTaxnoAndSendType(psdSendTaxRecordVO.getTaxNo(), "1");
            for (PsdSendTaxRecordVO sendTaxRecordVO : psdSendTaxRecordVOS) {
                if (sendTaxRecordVO.getApplySeq().equals(psdSendTaxRecordVO.getApplySeq())) {
                    continue;
                }
                //时间比记录的时间大则不需要回写
                if (LocalDateTime.ofInstant(sendTaxRecordVO.getCreateTime().toInstant(), ZoneId.systemDefault()).isAfter(localDateTime)) {
                    updateFlag = true;
                    psdSendTaxRecordVO.setHandNum(999);
                    return;
                }
            }
            updateFlag = true;
            //流水号
            psdSendMsgToTaxReqBean.setApplySeq(getSeq(preNlsCreditInfoVO.getGlobalSerno()));
            //纳税人识别号
            psdSendMsgToTaxReqBean.setTaxpyrIdntfNo(preNlsCreditInfoVO.getTaxIdentificationNumber());
            //登记序号
            psdSendMsgToTaxReqBean.setRgstSrlNo(preNlsCreditInfoVO.getSocialCreditCode());
            //授信失败原因描述
            psdSendMsgToTaxReqBean.setCrFailRsnDesc(psdSendTaxRecordVO.getApplyMsg());
            //授信额度
            psdSendMsgToTaxReqBean.setCrtLmt(0.00);
            //授信标识
            psdSendMsgToTaxReqBean.setCrIndr("N");
            //金融产品编号
            psdSendMsgToTaxReqBean.setFinPdNo(jrcpbh);
            //不良客户标识
            psdSendMsgToTaxReqBean.setBadCustIndr("N");
            //贷款余额
            psdSendMsgToTaxReqBean.setLoanAmt(0.00);
            //贷款金额
            psdSendMsgToTaxReqBean.setLoanBal(0.00);
            // 还款日期
            psdSendMsgToTaxReqBean.setRpymtDt(preNlsCreditInfoVO.getCreateDate());
            // 授信到期日
            psdSendMsgToTaxReqBean.setCrMtrDt(preNlsCreditInfoVO.getCreateDate());
            // 授信开始日
            psdSendMsgToTaxReqBean.setCrStrtDay(preNlsCreditInfoVO.getCreateDate());

            //纯粹信用贷款标志Y:是   N：不是
            psdSendMsgToTaxReqBean.setNetCrdtLoanFlg("Y");

            //首次贷款日期 String(8) 格式：YYYY-MM-DD 获取普税贷产品最小期限n'l's
            psdSendMsgToTaxReqBean.setFstCrdtDt(preNlsCreditInfoVO.getCreateDate());

            //贷款授信期限	String(10)	N
            psdSendMsgToTaxReqBean.setLoanCrTrm("12");

            //累计支用笔数	Double(10,0)	N
            psdSendMsgToTaxReqBean.setAcmlnUseCnt("0");

            //支用金额	Double(21,2)	N
            psdSendMsgToTaxReqBean.setExpnsUseAmt(new BigDecimal("0.00"));
            //贷款类型	String(7)	线上：1 或空均可
            psdSendMsgToTaxReqBean.setLoanTp("1");

            psdSendMsgToTaxRespBean = psdWdSendMsgToTaxService.applyPsdSendMsgToTax(psdSendMsgToTaxReqBean);
            psdSendTaxRecordVO.setHandStatus("Y");
            //修改预授信记录状态为失效
            updatePrenlsSts(preNlsCreditInfoVO);
            //次数改成999 回写状态置为成功
            psdSendTaxRecordVO.setHandStatus("Y");
            psdSendTaxRecordVO.setHandNum(999);
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, null);
            logger.info("发送信息给税局 预授信申请流水号【" + preNlsCreditInfoVO.getApplySeq() + "】发送信息税局成功");
        } catch (Exception e) {
            insertMsgRecord(psdSendTaxRecordVO, psdSendMsgToTaxReqBean, psdSendMsgToTaxRespBean, e);
            logger.error("发送信息给税局税务局信贷审批结果通知失败" + e.getMessage());
        } finally {
            if (updateFlag) {
                psdSendTaxRecordService.updateByPk(psdSendTaxRecordVO);
            }
        }
    }

    private void updatePrenlsSts(PreNlsCreditInfoVO preNlsCreditInfoVO) {
        preNlsCreditInfoVO.setStatus("06");
        preNlsCreditInfoService.updateByPk(preNlsCreditInfoVO);
    }

    /**
     * 根据纳税识别号获取如下信息
     * 获取产品首次贷款日期[0]
     * 获取产品支用次数[1]
     * 获取产品支用金额[2]
     * 获取产品的贷款余额[3]
     *
     * @param nlsCreditInfoVO
     * @return
     * @throws Exception
     */
    private String[] getFstCrdtDt(NlsCreditInfoVO nlsCreditInfoVO, PreNlsCreditInfoVO preNlsCreditInfoVO) throws Exception {
        //纳税识别号
        String taxIdentificationNumber = preNlsCreditInfoVO.getTaxIdentificationNumber();
        //查出所有的纳税识号对应的预授信申请记录
        List<PreNlsCreditInfoVO> preNlsCreditInfoVOS = preNlsCreditInfoService.queryByTaxNumber(taxIdentificationNumber);
        if (preNlsCreditInfoVOS == null || preNlsCreditInfoVOS.isEmpty()) {
            return new String[]{nlsCreditInfoVO.getApplyDate(), "0", "0.00", "0.00"};
        }
        //查出所有的授信申请记录
        List<NlsCreditInfoVO> nlsCreditInfoVOS = nlsCreditInfoService.queryInPreLmtApplySeq(preNlsCreditInfoVOS.stream().map(PreNlsCreditInfoVO::getApplySeq).distinct().collect(Collectors.toList()));
        if (nlsCreditInfoVOS == null || nlsCreditInfoVOS.isEmpty()) {
            return new String[]{nlsCreditInfoVO.getApplyDate(), "0", "0.00", "0.00"};
        }
        //查出所有的用信申请记录
        List<NlsApplyInfoVO> nlsApplyInfoVOS = nlsApplyInfoService.queryByLmtSeqs(nlsCreditInfoVOS.stream().map(NlsCreditInfoVO::getLmtApplySeq).distinct().collect(Collectors.toList()));
        if (nlsApplyInfoVOS == null || nlsApplyInfoVOS.isEmpty()) {
            return new String[]{nlsCreditInfoVO.getApplyDate(), "0", "0.00", "0.00"};
        }
        // 根据用信流水号获取借据信息
        List<AccLoanVO> accLoanVOS = accLoanService.queryByApplySqes(nlsApplyInfoVOS.stream().map(NlsApplyInfoVO::getApplySeq).distinct().collect(Collectors.toList()));
        if (accLoanVOS == null || accLoanVOS.isEmpty()) {
            return new String[]{nlsCreditInfoVO.getApplyDate(), "0", "0.00", "0.00"};
        }
        Collections.sort(accLoanVOS, (o1, o2) -> {
            try {
                return DateUtility.compareToDate(o1.getFirstDisbDate(), o2.getFirstDisbDate());
            } catch (BizException e) {
                e.printStackTrace();
            }
            return 0;
        });
        BigDecimal totaAmout = accLoanVOS.stream().map(AccLoanVO::getLoanAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totaBalance = accLoanVOS.stream().map(AccLoanVO::getLoanBalance).reduce(BigDecimal.ZERO, BigDecimal::add);
        return new String[]{accLoanVOS.get(0).getFirstDisbDate(), String.valueOf(accLoanVOS.size()), String.valueOf(totaAmout), String.valueOf(totaBalance)};
    }

    private final void insertMsgRecord(PsdSendTaxRecordVO psdSendTaxRecordVO, PsdSendMsgToTaxReqBean psdSendMsgToTaxReqBean, PsdSendMsgToTaxRespBean psdSendMsgToTaxRespBean, Exception e) {
        try {
            if (!Objects.isNull(e)) {
                taxNumber.add(psdSendTaxRecordVO.getTaxNo());
            }
            PsdSendTaxMessageRecordVO psdSendTaxMessageRecordVO = new PsdSendTaxMessageRecordVO();
            psdSendTaxMessageRecordVO.setId(UUID.randomUUID().toString());
            psdSendTaxMessageRecordVO.setSendTaxRecordId(psdSendTaxRecordVO.getId());
            psdSendTaxMessageRecordVO.setSendTime(new Date());
            psdSendTaxMessageRecordVO.setSendMessage(Objects.isNull(psdSendMsgToTaxReqBean) ? "" : JSON.toJSONString(psdSendMsgToTaxReqBean));
            psdSendTaxMessageRecordVO.setRetMessage(!Objects.isNull(e) ? e.getMessage() : JSON.toJSONString(psdSendMsgToTaxRespBean));
            psdSendTaxMessageRecordVO.setCreateTime(new Date());
            psdSendTaxMessageRecordService.insert(psdSendTaxMessageRecordVO);
        } catch (Exception ex) {
            logger.error("插入回写税局接口调用信息记录表发生异常", ex);
        }
    }

    private String getSeq(String bakSeq) {
        try {
            PatternedLimitableSeqService sequenceService = SpringContextUtils.getBean(PatternedLimitableSeqService.class);
            return sequenceService.getPatternedSequence("ESB", pattern);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("获取全局流水号失败");
            return bakSeq;
        }
    }

    private static final PatternDescriptor pattern =
            DefaultPatternDescriptor.of(ESBClientConstance.CnsmrSysNo +
                    YEAR_2 + MONTH + DAY + HOUR + MIN + SECOND + SEQ, 6);
}
